﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;


namespace WebCrawler
{
    public partial class MainForm : Form
    {
        bool executedH = false;
        bool executedW = false;
        bool alreadyFocused = false;
        private String _crawlerurl;
        private Timer _timer;
        private Status _status = Status.GetInstance();
        private WebCrawlerController _crawler;
        private String crawlerUrl;
        private int limit;
        private BackgroundWorker worker;

        public MainForm()
        {
            InitializeComponent();//initializes all the components in the GUI.
            HideAndSeek();//hides the components in Mainform.cs, which isn't used yet. So only the navigation elements are loaded.
            this.Size = new Size(644, 75);//sets the initialized size of Mainform.cs
            addressTxt.GotFocus += addressTxt_GotFocus;
            addressTxt.MouseUp += addressTxt_MouseUp;
            addressTxt.Leave += addressTxt_Leave;
        }

        #region Resizing
        private void HideAndSeek()
        {
            treeView.Visible = false;
            webBrowser.Visible = false;
            DepthCmb.Visible = false;
            label2.Visible = false;
        }

        private void NoMoreHiding()
        {
            treeView.Visible = true;
            webBrowser.Visible = true;
            DepthCmb.Visible = true;
            label2.Visible = true;
        }

        public void ResizeH()
        {
            for (int height = 75; height <= 768; height++)
            {
                this.Height = height;
                System.Threading.Thread.Sleep(0);
            }
            executedH = true;
        }

        public void ResizeW()
        {
            for (int width = 644; width <= 1024; width++)
            {
                this.Width = width;
                System.Threading.Thread.Sleep(0);
            }
            executedW = true;
        }

        public void ResizeSW()
        {
            for (int width = 1024; width >= 644; width--)
            {
                this.Width = width;
                System.Threading.Thread.Sleep(0);
            }
            executedW = false;
        }

        public void ResizeSH()
        {
            for (int height = 768; height >= 75; height--)
            {
                this.Height = height;
                System.Threading.Thread.Sleep(0);
            }
            executedH = false;
        }
        #endregion Resizing

        #region StartCrawler

        private void addressTxt_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                address();
                
                alreadyFocused = false;
                if (executedH == false && executedW == false)
                {
                    ResizeH();
                    ResizeW();
                    NoMoreHiding();
                }
            }

            if (e.KeyCode == Keys.Delete && executedW == true && executedH == true)
            {
                ResizeSW();
                ResizeSH();
                HideAndSeek();
                executedW = false;
                executedH = false;
            }
        }

        private void address()
        {
            String url = addressTxt.Text;
            limit = int.Parse(DepthCmb.Text);
            Navigate(url);
        }

        public void Navigate(String address)
        {
            if (String.IsNullOrEmpty(address)) return;
            if (address.Equals("about:blank")) return;
            if (address.StartsWith(@"http://") || address.StartsWith(@"https://"))
            {
            }

            else
            {
                address = "http://" + address;
            }

            try
            {
                crawlerUrl = address;
                StartCrawling();

                webBrowser.Navigate(address);
            }
            catch (System.UriFormatException)
            {
                return;
            }
        }

        #endregion StartCrawler

        #region MegaGodtWork

        private void StartCrawling()
        {
            treeView.Nodes.Clear();
            DoBackgroundWork();
        }

        private void DoBackgroundWork()//Så man stadig kan navigere rundt på hjemmesiden
        {
            worker = new BackgroundWorker();
            worker.WorkerReportsProgress = true;
            worker.ProgressChanged += ProgressChanged;
            worker.DoWork += DoWork;
            worker.RunWorkerCompleted += WorkerCompleted;
            worker.RunWorkerAsync();
        }

        void ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            _timer = new System.Windows.Forms.Timer { Interval = 500, Enabled = true };
            _timer.Start();
            _timer.Tick += new EventHandler(UpdateStatus);
        }

        void UpdateStatus(object obj, EventArgs e)
        {
            treeView.Nodes.Clear();
            treeView.Nodes.Add(_status.CrawlerStatus);
        }

        void DoWork(object sender, DoWorkEventArgs e)
        {
            BackgroundWorker worker = sender as BackgroundWorker;

            worker.ReportProgress(0);

            _crawler = new WebCrawlerController(crawlerUrl, limit);
        }

        private TreeNode GetNode(Vertex v)
        {
            treeView.Nodes.Clear();
            return treeView.Nodes.Add(v.Title);
        }

        public void WorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            _timer.Stop();

            treeView.Nodes.Clear();

            Vertex v = _crawler.StartVertex;

            TreeNode node = treeView.Nodes.Add(v.Doc.Title);
            node.Tag = v.Url;

            AddNodesForEdges(node, v);

            node.Expand();

            treeView.NodeMouseClick += this.treeView_TreeNodeMouseClick;
        }

        #endregion MegaGodtWork

        private static void AddNodesForEdges(TreeNode node, Vertex v)
        {
            foreach (Edge e in v.Edges)
            {
                TreeNode nodeX = node.Nodes.Add(e.To.Title);
                nodeX.Tag = e.To.Url;
                AddNodesForEdges(nodeX, e.To);
            }
        }

        private void webBrowser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
        {
            addressTxt.Text = webBrowser.Url.ToString();
        }

       


        private void addressTxt_Leave(object sender, EventArgs e)
        {
            alreadyFocused = false;
        }

        private void addressTxt_MouseUp(object sender, MouseEventArgs e)
        {
            if (!alreadyFocused && this.addressTxt.SelectionLength == 0)
            {
                {
                    alreadyFocused = true;
                    this.addressTxt.SelectAll();
                }
            }
        }

        void addressTxt_GotFocus(object sender, EventArgs e)
        {
            // Select all text only if the mouse isn't down.
            // This makes tabbing to the textbox give focus.
            if (MouseButtons == MouseButtons.None)
            {
                this.addressTxt.SelectAll();
                alreadyFocused = true;
            }
        }

        private void treeView_TreeNodeMouseClick(object sender, System.Windows.Forms.TreeNodeMouseClickEventArgs e)
        {
            webBrowser.Url = new Uri(e.Node.Tag.ToString()); 
        }

        private void backBtn_Click(object sender, EventArgs e)
        {
            webBrowser.GoBack();
        }

        private void forwardBtn_Click(object sender, EventArgs e)
        {
            webBrowser.GoForward();
        }

        private void homeBtn_Click(object sender, EventArgs e)
        {
            limit = int.Parse(DepthCmb.Text);
            Navigate("http://public.ucn.dk/fen/testsite/index.htm");
            if (executedH == false && executedW == false)
            {
                ResizeH();
                ResizeW();
                NoMoreHiding();
            }
        }

        private void MainForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (executedW == true && executedH == true)
            {
                HideAndSeek();
                ResizeSW();
                ResizeSH();
                executedW = false;
                executedH = false;
            }
        }
    }
}
